package com.leaf.u.basehttp.http.request;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;

import com.leaf.u.basehttp.http.HttpEngine;
import com.leaf.u.basehttp.http.ResponseConvert;
import com.leaf.u.basehttp.http.inter.RequestInterceptor;
import com.leaf.u.basehttp.http.okimpl.LeafRequest;
import com.leaf.u.basehttp.http.response.OnQueueListener;
import com.leaf.u.basehttp.utils.MD5Tools;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by bz on 2017/5/17.
 */

public class LeafCallQueue {
    Map<String, AsyncCall> unfinish = new HashMap<>();
    Map<String, AsyncCall> finish = new HashMap<>();
    HttpEngine httpEngine;
    OnQueueListener listener;
    String uid;
    private List<RequestInterceptor> interceptors = new ArrayList<>();
    private ResponseConvert convert;

    public LeafCallQueue(HttpEngine httpEngine) {
        this.httpEngine = httpEngine;
    }

    public LeafCallQueue addInterceptor(RequestInterceptor interceptor) {
        this.interceptors.add(interceptor);
        return this;
    }

    public LeafCallQueue setResponseConvert(ResponseConvert convert) {
        this.convert = convert;
        return this;
    }

    public String uid() {
        return this.uid;
    }

    public boolean isFinish() {
        return unfinish.size() == 0;
    }

    public List<AsyncCall> getCallQueue() {
        List<AsyncCall> list = new ArrayList<>();
        Collection<AsyncCall> values = unfinish.values();
        list.addAll(values);
        return list;
    }

    private List<AsyncCall> getFinishQueue() {
        List<AsyncCall> list = new ArrayList<>();
        Collection<AsyncCall> values = finish.values();
        list.addAll(values);
        return list;
    }


    public void finish(AsyncCall call) {
        if (unfinish.size() == 0) {
            return;
        }
        boolean containsKey = unfinish.containsKey(call.uid());
        if (containsKey) {
            AsyncCall remove = unfinish.remove(call.uid());
            finish.put(call.uid(), remove);
            listener.onProceed(call, finish.size(), unfinish.size());
        }
        if (unfinish.size() == 0) {
            httpEngine.dispatcher().finished(this);
            new Handler(Looper.getMainLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    listener.onCompled(getFinishQueue());
                }
            }.sendEmptyMessage(0);
        }

    }

    public AsyncCall newCall(LeafRequest request) {
        AsyncCall call = new AsyncCall(httpEngine, request, interceptors, convert);
        unfinish.put(call.uid(), call);
        return call;
    }

    public void execute(OnQueueListener listener) {
        this.listener = listener;
        Set<String> strings = unfinish.keySet();
        StringBuffer strb = new StringBuffer();
        for (String string : strings) {
            strb.append(string);
        }
        this.uid = MD5Tools.MD5(strb.toString());
        httpEngine.dispatcher().enqueue(this);
    }

}
